/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */
#include "vino.h"
#include "common.h"

#include <QGSettings>

Vino::Vino() : mFirstLoad(true)
{
    pluginName = tr("Vino");
    pluginType = SYSTEM;
}

Vino::~Vino()
{
}

QString Vino::plugini18nName()
{
    return pluginName;
}

int Vino::pluginTypes()
{
    return pluginType;
}

QWidget *Vino::pluginUi()
{
    if (mFirstLoad) {
        mFirstLoad = false;
        mVinoWidget = new VinoUi;
        mVinoDBus = new QDBusInterface("org.ukui.ukcc.session",
                                        "/Vino",
                                        "org.ukui.ukcc.session.Vino",
                                        QDBusConnection::sessionBus(), this);
        if (!mVinoDBus->isValid()) {
            qCritical() << "org.ukui.ukcc.session.Vino DBus error:" << mVinoDBus->lastError();
        } else {
            initStatus();
            initConnection();
        }
    }

    return mVinoWidget;
}

const QString Vino::name() const
{
    return QStringLiteral("Vino");
}

bool Vino::isShowOnHomePage() const
{
    return false;
}

QIcon Vino::icon() const
{
    return QIcon::fromTheme("folder-remote-symbolic");
}

bool Vino::isEnable() const
{
    return !Common::isCommunity() && !Common::isWayland() && isExistVino();
}

bool Vino::isExistVino() const
{
    return QGSettings::isSchemaInstalled(QByteArray("org.gnome.Vino"));
}

void Vino::setVinoService(bool status)
{
    QDBusInterface vinoIfc("org.ukui.SettingsDaemon",
                           "/org/ukui/SettingsDaemon/Sharing",
                           "org.ukui.SettingsDaemon.Sharing",
                           QDBusConnection::sessionBus());
    if (vinoIfc.isValid()) {
        if (status) {
            vinoIfc.call("EnableService", "vino-server");
        } else {
            vinoIfc.call("DisableService", "vino-server");
        }
    }
}

void Vino::enableSlot(bool status)
{
    mVinoWidget->setFrameVisible(status);
    setVinoService(status);
}

void Vino::viewBoxSlot(bool status)
{
    mVinoDBus->call("setVinoKey", kVinoViewOnlyKey, !status);
}

void Vino::accessSlot(bool status)
{
    mVinoDBus->call("setVinoKey", kVinoPromptKey, status);
}

void Vino::pwdEnableSlot(bool status)
{
    if (status) {
        mVinoWidget->getPwdinputBtn()->setVisible(mVinoDBus->property("password").toString() == "keyring" ? false:true);
        mVinoWidget->getPwdinputBtn()->setText(QByteArray::fromBase64(mVinoDBus->property("password").toString().toLatin1()));
        pwdInputSlot();
        mVinoWidget->getPwdinputBtn()->setVisible(status);
        if (mVinoDBus->property("method").toString() == "none") {
            mVinoWidget->getSecurityPwdWidget()->setChecked(false);
        }
    } else {
        mVinoWidget->getPwdinputBtn()->setVisible(false);
        mVinoDBus->call("setVinoKey", kAuthenticationKey, "none");
    }
}

void Vino::pwdInputSlot()
{
    InputPwdDialog *dialog = new InputPwdDialog(mVinoWidget);
    dialog->exec();
    mVinoWidget->getPwdinputBtn()->setText(QByteArray::fromBase64(mVinoDBus->property("password").toString().toLatin1()));
}

void Vino::initConnection()
{
    connect(mVinoWidget->getEnableWidget(), &SwitchWidget::stateChanged, this, [=](bool status) {
        Common::buriedSettings(QStringLiteral("Vino"), "whether allow others to connect to your desktop remotely", QString("settings"), status ? "true" : "false");
        enableSlot(status);
    });
    connect(mVinoWidget->getViewWidget(), &SwitchWidget::stateChanged, this, [=](bool status) {
        Common::buriedSettings(QStringLiteral("Vino"), "whether allow others to control your desktop remotely", QString("settings"), status ? "true" : "false");
        viewBoxSlot(status);
    });
    connect(mVinoWidget->getSecurityWidget(), &SwitchWidget::stateChanged, this, [=](bool status) {
        Common::buriedSettings(QStringLiteral("Vino"), "whether to confirm each visit for the local mach", QString("settings"), status ? "true" : "false");
        accessSlot(status);
    });
    connect(mVinoWidget->getSecurityPwdWidget(), &SwitchWidget::stateChanged, this, [=](bool status) {
        Common::buriedSettings(QStringLiteral("Vino"), "whether password verification is required", QString("settings"), status ? "true" : "false");
        pwdEnableSlot(status);
    });
    connect(mVinoWidget->getPwdinputBtn(), &QPushButton::clicked, this, [=]() {
        Common::buriedSettings(QStringLiteral("Vino"), "set password", QString("clicked"));
        pwdInputSlot();
    });
}

void Vino::initStatus()
{
    bool isShared = mVinoDBus->property("isViewOnly").toBool();
    bool isPrompt = mVinoDBus->property("isPrompt").toBool();

    QString pwd = mVinoDBus->property("method").toString();
    QString secpwd = mVinoDBus->property("password").toString();

    mVinoWidget->getSecurityWidget()->setChecked(isPrompt);
    mVinoWidget->getViewWidget()->setChecked(!isShared);
    if (pwd == "vnc") {
        if (secpwd == "keyring") {
            mVinoWidget->getSecurityPwdWidget()->setChecked(false);
            mVinoWidget->getPwdinputBtn()->hide();
            mVinoDBus->call("setVinoKey", kAuthenticationKey, "none");
        } else {
            mVinoWidget->getSecurityPwdWidget()->setChecked(true);
            mVinoWidget->getPwdinputBtn()->setText(QByteArray::fromBase64(secpwd.toLatin1()));
        }
    } else {
        mVinoWidget->getSecurityPwdWidget()->setChecked(false);
        mVinoWidget->getPwdinputBtn()->setVisible(false);
    }

    mVinoWidget->setFrameVisible(mVinoDBus->property("isActive").toBool());
}

